package com.newtouch.bxzs.enterprise.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newtouch.bxzs.common.base.BaseErrorEnum;
import com.newtouch.bxzs.common.base.BaseException;
import com.newtouch.bxzs.common.base.em.*;
import com.newtouch.bxzs.common.base.model.PushCustomerRecord;
import com.newtouch.bxzs.common.base.model.bo.CompanyParameterGroupBO;
import com.newtouch.bxzs.common.base.util.CooperationCompanyUtils;
import com.newtouch.bxzs.common.base.util.RedisUtils;
import com.newtouch.bxzs.common.base.util.SendHttpRequestUtils;
import com.newtouch.bxzs.common.base.util.UserDetailUtil;
import com.newtouch.bxzs.enterprise.mapper.PushCustomerRecordMapper;
import com.newtouch.bxzs.enterprise.mapper.PushCustomerRecordProductMapMapper;
import com.newtouch.bxzs.enterprise.model.bo.*;
import com.newtouch.bxzs.enterprise.model.vo.CustomerCndVO;
import com.newtouch.bxzs.enterprise.model.vo.PushCustomerRecordVO;
import com.newtouch.bxzs.enterprise.service.PushCustomerService;
import com.newtouch.bxzs.enterprise.util.FieldCheckUtils;
import lombok.SneakyThrows;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 客户推送serviceImpl类
 * <p>
 * <b>History:</b>
 * <table border="1">
 * <tr>
 * <th>Date</th>
 * <th>Operator</th>
 * <th>Memo</th>
 * </tr>
 * <tr>
 * <td>2021/1/12 14:18</td>
 * <td>Amour</td>
 * <td>Create</td>
 * </tr>
 * </table>
 *
 * @author Amour
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
public class PushCustomerServiceImpl implements PushCustomerService {

	private static final Log logger = LogFactory.getLog(PushCustomerServiceImpl.class);

	@Autowired
	private PushCustomerRecordMapper pushCustomerRecordMapper;

	@Autowired
	private PushCustomerRecordProductMapMapper pushProductMapper;

	@Autowired
	private RedisUtils redisUtils;

	@Autowired
	private CooperationCompanyUtils cooperationCompanyUtils;

	private final String IS_TRUE = "1";
	private final String ORGANIZATION_CODE = "organizationCode";
	private final String COOPERATION_ORGANIZATION_CODE = "cooperationOrganizationCode";

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.newtouch.bxzs.enterprise.service.PushCustomerService#savePushRecord(
	 * com.newtouch.bxzs.enterprise.model.vo.PushCustomerRecordVO)
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public String savePushRecord(PushCustomerRecordVO pushCustomerRecordVO) {
		logger.info("调用PushCustomerServiceImpl.savePushRecord()");
		if (StringUtils.isEmpty(pushCustomerRecordVO.getDataSource())){
			throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
		}
		this.decidePushCustomerRecord(pushCustomerRecordVO);
		if (PushSourceEnum.POLICY_INTENTION_PUSH.getCode().equals(pushCustomerRecordVO.getPushSource())){
			FieldCheckUtils.checkAddPolicyPush(pushCustomerRecordVO.getPolicyNumber(),
					pushCustomerRecordVO.getIntentionRegistrationDescription());
		}
		PushCustomerRecord pushCustomerRecord = new PushCustomerRecord();
		BeanUtils.copyProperties(pushCustomerRecordVO, pushCustomerRecord);
		pushCustomerRecord.setPushCustomerStatus(PushStatusEnum.NOT_RECEIVED.getCode());
		pushCustomerRecord.setCreateInformation(UserDetailUtil.getUserDetail().getUserId(), new Date());
		if (pushCustomerRecordMapper.insert(pushCustomerRecord) <= 0) {
			throw new BaseException("-1", "添加失败");
		} else {
			if (pushCustomerRecordVO.getProduct().size() > 0) {
				int saveProduct = pushProductMapper.savePushProduct(pushCustomerRecordVO.getProduct(),
						pushCustomerRecord.getPushCustomerRecordId());
				if (saveProduct <= 0) {
					throw new BaseException("-1", "客户推送产品添加失败");
				}
			}
			SendPushRecordBO sendPushRecordBO = new SendPushRecordBO();
			BeanUtils.copyProperties(pushCustomerRecord, sendPushRecordBO);
			sendPushRecordBO.setProduct(pushCustomerRecordVO.getProduct());
			sendPushRecordBO.setIntentionRegistrationType(pushCustomerRecord.getIntentionRegistrationType());
			SendHttpRequestUtils<SendPushRecordBO> sendHttpRequest = new SendHttpRequestUtils<>();
			// 判断本端为银行还是保险
			String url;
			if (DistributionTypeEnum.BANK.getCode().equals(redisUtils.get(SystemParamsEnum.BANKING_OR_INSURANCE.getCode()))) {
				// 发送推送信息至对端合作公司
				url = cooperationCompanyUtils.getCompanyUrl(pushCustomerRecordVO.getDataSource(),
						CompanyParameterTypeEnum.PUSH_CUSTOMER.getCode());
				if (StringUtils.isEmpty(url)) {
					url = cooperationCompanyUtils.getCompanyUrlById(this.addRedisCompanyUrl(),
							pushCustomerRecordVO.getDataSource(), CompanyParameterTypeEnum.PUSH_CUSTOMER.getCode());
				}
			} else {
				url = redisUtils.get(SystemParamsEnum.PUSH_CUSTOMER.getCode());
			}
			if ((Boolean) sendHttpRequest.sendHttpRequest(sendPushRecordBO, url)) {
				return "成功推送";
			} else {
				return "该个人客户未达到推送标准，无法推送";
			}
		}
	}

	@Override
	public Page<PushCustomerRecordBO> getCustomerPushList(CustomerCndVO customerCnd) {
		logger.info("调用PushCustomerServiceImpl.getCustomerPushList()");
		Page<PushCustomerRecordBO> page = new Page<>(customerCnd.getCurrentPage(), customerCnd.getPageSize());
		// 查询客户推送记录根据用户工号、推送来源和客户姓名查询
		if (StringUtils.isEmpty(UserDetailUtil.getUserDetail().getUserJobNumber())) {
			throw new BaseException(BaseErrorEnum.USER_NOT_EXISTS);
		}
		if (PushSourceEnum.PRODUCT_INTENTION_PUSH.getCode().equals(customerCnd.getPushSource())
		|| PushSourceEnum.CUSTOMER_PUSH.getCode().equals(customerCnd.getPushSource())
		||PushSourceEnum.ENTERPRISE_CUSTOMER_PUSH.getCode().equals(customerCnd.getPushSource())){
			//产品意向登记/个人客户推送/企业客户推送 展示在同一界面
			customerCnd.setPushSource("");
		}
		if (PushSourceEnum.POLICY_INTENTION_PUSH.getCode().equals(customerCnd.getPushSource())) {
			// 判断客户推送来源是否为保单服务意向推送
			if (customerCnd.getPushStartTime() != null && customerCnd.getPushEndTime() != null) {
				FieldCheckUtils.checkPolicyPush(customerCnd.getPushStartTime(),customerCnd.getPushEndTime(),
						customerCnd.getPolicyNumber(),customerCnd.getCustomerCertificateType(),
						customerCnd.getCustomerCertificateNumber());
				customerCnd.setPushStartTime(DateUtil.beginOfDay(customerCnd.getPushStartTime()));
				customerCnd.setPushEndTime(DateUtil.endOfDay(customerCnd.getPushEndTime()));
			} else {
				// 推送查询条件默认为当前时间-7
				customerCnd.setPushStartTime(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -7)));
				customerCnd.setPushEndTime(DateUtil.endOfDay(new Date()));
			}
			return pushCustomerRecordMapper.getPolicyCustomerPushList(page, customerCnd,
					UserDetailUtil.getUserDetail().getUserJobNumber());
		}
		return pushCustomerRecordMapper.getCustomerPushList(page, customerCnd,
				UserDetailUtil.getUserDetail().getUserJobNumber(),PushStatusEnum.HANDLED.getCode());
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public String revocationPush(String pushCustomerRecordId) {
		logger.info("调用PushCustomerServiceImpl.revocationPush()");
		if (StringUtils.isEmpty(pushCustomerRecordId)) {
			throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
		}
		// 整理发送至对端的信息
		RevocationCustomerBO revocationCustomerBO = new RevocationCustomerBO();
		revocationCustomerBO.setPushCustomerRecordId(pushCustomerRecordId);
		revocationCustomerBO.setPushCustomerStatus(PushStatusEnum.WITHDRAW.getCode());
		// 发送撤回消息给对端
		SendHttpRequestUtils<RevocationCustomerBO> sendHttpRequest = new SendHttpRequestUtils<>();
		// 判断本端为银行还是保险
		String url;
		if (DistributionTypeEnum.BANK.getCode().equals(redisUtils.get(SystemParamsEnum.BANKING_OR_INSURANCE.getCode()))) {
			// 发送推送信息至对端合作公司
			String unifiedSocialCreditCode = pushCustomerRecordMapper.getCooperationCompanyId(pushCustomerRecordId);
			if (StringUtils.isEmpty(unifiedSocialCreditCode)) {
				throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
			} else {
				url = cooperationCompanyUtils.getCompanyUrl(unifiedSocialCreditCode,
						CompanyParameterTypeEnum.REPEAL_PUSH.getCode());
				if (StringUtils.isEmpty(url)) {
					url = cooperationCompanyUtils.getCompanyUrlById(this.addRedisCompanyUrl(), unifiedSocialCreditCode,
							CompanyParameterTypeEnum.REPEAL_PUSH.getCode());
				}
			}
		} else {
			url = redisUtils.get(SystemParamsEnum.REPEAL_PUSH.getCode());
		}
		if ((Boolean) sendHttpRequest.sendHttpRequest(revocationCustomerBO, url)) {
			// 对端发送成功后就修改本地推送状态
			PushCustomerRecord pushCustomerRecord = new PushCustomerRecord();
			pushCustomerRecord.setUpdateStatus(pushCustomerRecordId, PushStatusEnum.WITHDRAW.getCode(),
					UserDetailUtil.getUserDetail().getUserId(), new Date());
			int updateCount = pushCustomerRecordMapper.updateById(pushCustomerRecord);
			if (updateCount <= 0) {
				throw new BaseException("-1", "撤回失败");
			} else {
				return "撤回成功";
			}
		} else {
			return "对端客户已接收不可撤回";
		}

	}

	@Override
	public PushCustomerRecord getPushRecordById(String pushCustomerRecordId) {
		logger.info("调用PushCustomerServiceImpl.getPushRecordById()");
		if (StringUtils.isEmpty(pushCustomerRecordId)) {
			throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
		}
		return pushCustomerRecordMapper.selectById(pushCustomerRecordId);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean updatePushStatus(String pushCustomerRecordId, String pushCustomerStatus,boolean updateStatus) {
		logger.info("调用PushCustomerServiceImpl.updatePushStatus()");
		if (StringUtils.isEmpty(pushCustomerRecordId)) {
			throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
		}
		PushCustomerRecord pushCustomerRecord = new PushCustomerRecord();
		pushCustomerRecord.setUpdateStatus(pushCustomerRecordId, pushCustomerStatus, null, new Date());
		// 对端接收客户后，修改本端客户推送状态
		QueryWrapper<PushCustomerRecord> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("PUSH_CUSTOMER_RECORD_ID", pushCustomerRecordId);
		if (updateStatus){
			queryWrapper.isNull("UPDATE_TIME");
		}
		int updateCount = pushCustomerRecordMapper.update(pushCustomerRecord, queryWrapper);
		if (updateCount <= 0) {
			return false;
		} else {
			return true;
		}
	}

	@Override
	public void decidePushCustomerRecord(PushCustomerRecordVO pushCustomerRecordVO) {
		//客户推送必传参数判断
		if (pushCustomerRecordVO == null || StringUtils.isEmpty(pushCustomerRecordVO.getCustomerName())
				|| StringUtils.isEmpty(pushCustomerRecordVO.getCustomerPhone())
				|| StringUtils.isEmpty(pushCustomerRecordVO.getCooperationCompanyUserJobNumber())
				|| StringUtils.isEmpty(pushCustomerRecordVO.getCooperationCompanyUserName())
				|| StringUtils.isEmpty(pushCustomerRecordVO.getCooperationCompanyUserCertificateType())
				|| StringUtils.isEmpty(pushCustomerRecordVO.getCooperationCompanyUserCertificateNumber())
				|| StringUtils.isEmpty(pushCustomerRecordVO.getPushSource())
				) {
			throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
		}
		if (PushSourceEnum.ENTERPRISE_CUSTOMER_PUSH.getCode().equals(pushCustomerRecordVO.getPushSource())){
			//企业客户推送必填参数
			if (StringUtils.isEmpty(pushCustomerRecordVO.getUnifiedSocialCreditCode())
					|| StringUtils.isEmpty(pushCustomerRecordVO.getEnterpriseCustomerName())){
				throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
			}
		}else {
			//个人客户推送必填参数
			if (StringUtils.isEmpty(pushCustomerRecordVO.getCustomerCertificateType())
					|| StringUtils.isEmpty(pushCustomerRecordVO.getCustomerCertificateNumber())
					|| StringUtils.isEmpty(pushCustomerRecordVO.getCustomerSex())
					|| StringUtils.isEmpty(pushCustomerRecordVO.getCustomerId())) {
				throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
			}
			if (pushCustomerRecordVO.getPushSource() == PushSourceEnum.PRODUCT_INTENTION_PUSH.getCode()) {
				// 判断产品意向登记必录项
				if (pushCustomerRecordVO.getProduct().size() <= 0) {
					throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
				}
			} else if (pushCustomerRecordVO.getPushSource() == PushSourceEnum.POLICY_INTENTION_PUSH.getCode()) {
				// 判断保单服务意向登记必录项
				if (StringUtils.isEmpty(pushCustomerRecordVO.getPolicyNumber())
						|| StringUtils.isEmpty(pushCustomerRecordVO.getIntentionRegistrationDescription())
						|| StringUtils.isEmpty(pushCustomerRecordVO.getIntentionRegistrationType())) {
					throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
				}
			}
		}
		//客户推送进行推送决策树判断
		if (StringUtils.isEmpty(pushCustomerRecordVO.getPushCustomerRecordId())){
            /*
             * 1.通过缓存获取保护期时间参数. 2.根据条件查询推送记录. 3.存在推送记录则进行决策树判断，满足条件时不允许推送
             */
//		String param = redisUtils.get(SystemParamsEnum.PERSONAL_INSURANCE_PUSH_PROTECTION_PERIOD.getCode());
//		Integer periodTime = StringUtils.isEmpty(param) ? 0 : Integer.parseInt(param) * -1;
//		Date periodDate = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, periodTime);
//		Integer result = pushCustomerRecordMapper.getPushPeriodRecord(pushCustomerRecordVO.getCustomerId(),
//				DateUtil.beginOfDay(periodDate), DateUtil.endOfDay(periodDate), pushCustomerRecordVO.getUserJobNumber(),
//				pushCustomerRecordVO.getCooperationCompanyUserJobNumber(),
//				pushCustomerRecordVO.getCooperationCompanyUserCertificateType(),
//				pushCustomerRecordVO.getCooperationCompanyUserCertificateNumber());
//		if (result > 0) {
//			throw new BaseException(BaseErrorEnum.CUSTOMER_PERIOD);
//		}
            /*
             * 1.查询决策条件配置
             * 2.是否有推送记录
             * 3.是否在推送保护期
             * 4.是否同一推送人行政业务机构
             * 5.是否同一推送人条线
             * 6.是否同一接收人条线
             * 7.是否同一接收人
             */
            //是否开启推送记录判断
            String policyPushRecord = redisUtils.get(SystemParamsEnum.POLICY_PUSH_RECORD.getCode());
            //是否开启决策条件-是否在推送保护期
            String policyPushProtectionPeriod = redisUtils.get(SystemParamsEnum.POLICY_PUSH_PROTECTION_PERIOD.getCode());
            //是否开启决策条件-是否同一推送人条线
            String policyPusherLine = redisUtils.get(SystemParamsEnum.POLICY_PUSHER_LINE.getCode());
            //是否开启决策条件-是否同一接收人条线
            String policyReceiverLine = redisUtils.get(SystemParamsEnum.POLICY_RECEIVER_LINE.getCode());
            //是否开启决策条件-是否同一接收人
            String policyReceiver = redisUtils.get(SystemParamsEnum.POLICY_RECEIVER.getCode());
            if(IS_TRUE.equals(policyPushRecord)){
                Date periodBeginDate = null;
                Date periodEndDate = null;
                //保护期
                if(IS_TRUE.equals(policyPushProtectionPeriod)){
                    String param = redisUtils.get(SystemParamsEnum.PERSONAL_INSURANCE_PUSH_PROTECTION_PERIOD.getCode());
                    int periodTime = StringUtils.isEmpty(param) ? 0 : Integer.parseInt(param) * -1;
                    Date periodDate = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, periodTime);
                    periodBeginDate = DateUtil.beginOfDay(periodDate);
                    periodEndDate = DateUtil.endOfDay(periodDate);
                }
                String cooperationCompanyUserJobNumber = null;
                String cooperationUserCertificateType = null;
                String cooperationUserCertificateNumber = null;
                //是否同一接收人
                if(IS_TRUE.equals(policyReceiver)){
                    cooperationCompanyUserJobNumber = pushCustomerRecordVO.getCooperationCompanyUserJobNumber();
                    cooperationUserCertificateType = pushCustomerRecordVO.getCooperationCompanyUserCertificateType();
                    cooperationUserCertificateNumber = pushCustomerRecordVO.getCooperationCompanyUserCertificateNumber();
                }
                Integer result = pushCustomerRecordMapper.getPushPeriodRecord(pushCustomerRecordVO.getCustomerId(),
                        periodBeginDate, periodEndDate, null,
                        cooperationCompanyUserJobNumber,
                        cooperationUserCertificateType,
                        cooperationUserCertificateNumber,
						pushCustomerRecordVO.getUnifiedSocialCreditCode());
                if (result > 0) {
                    throw new BaseException(BaseErrorEnum.SATISFIED_POLICY);
                }
                //获取推送人和接收人的机构编码
                List<Map<String, String>> pushOrganCode = pushCustomerRecordMapper.getPushOrganCode(pushCustomerRecordVO.getCustomerId(),pushCustomerRecordVO.getUnifiedSocialCreditCode());
                //是否同一推送人条线
                if (IS_TRUE.equals(policyPusherLine)){
                    //获取用户机构编码
                    String ownOrganCode = pushCustomerRecordMapper.getOwnOrganCode(UserDetailUtil.getUserDetail().getUserJobNumber());
                    pushOrganCode.stream().forEach(e -> {
                        //是否同一推送人条线
                        if (ownOrganCode.equals(e.get(ORGANIZATION_CODE))){
                            throw new BaseException(BaseErrorEnum.SATISFIED_POLICY);
                        }
                    });
                }
                //接收人是否为同一机构
                if (IS_TRUE.equals(policyReceiverLine)){
                    //获取接收人机构编码
                    String cooperationOrganCode = pushCustomerRecordMapper.getcooperationOrganCode(pushCustomerRecordVO.getCooperationCompanyUserJobNumber());
                    pushOrganCode.stream().forEach(e -> {
                        //是否同一接收人条线
                        if (cooperationOrganCode.equals(e.get(COOPERATION_ORGANIZATION_CODE))){
                            throw new BaseException(BaseErrorEnum.SATISFIED_POLICY);
                        }
                    });
                }
            }
        }
	}

	@Override
	public CooperationUserBO getgetReceiver(String policyNumber) {
		if (StringUtils.isEmpty(policyNumber)) {
			throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
		}
		return pushCustomerRecordMapper.getgetReceiver(policyNumber,UserDetailUtil.getUserDetail().getUserJobNumber());
	}

	@SneakyThrows
	@Override
	public List<CompanyParameterGroupBO> addRedisCompanyUrl() {
		List<CompanyParameterGroupBO> companyUrl = pushCustomerRecordMapper.getCompanyUrl();
		if (CollectionUtil.isNotEmpty(companyUrl)) {
			for (CompanyParameterGroupBO companyParameterGroup : companyUrl) {
				redisUtils.getAndSet(companyParameterGroup.getUnifiedSocialCreditCode(),
						JSON.toJSONString(companyParameterGroup.getCompanyParameter()));
			}
		}
		return companyUrl;
	}

	@Override
	public EnterpriseCustomerDetailBO getEnterpriseCustomerByCode(String unifiedSocialCreditCode,String userJobNumber) {
		return pushCustomerRecordMapper.getEnterpriseCustomerByCnd(unifiedSocialCreditCode,userJobNumber);
	}
}
